! 维度工厂
module ntree_factory_m

#if defined __NATIVE
    use, intrinsic :: iso_fortran_env, only: rk => real64
#else
    use &
        config_m, only: rk
#endif
    use shape_m, only: point_t, shape_t, cuboid_t, cube_t, square_t, rectangle_t, line_t, circle_t, sphere_t
    use ntree_m, only: ntree_t, make_ntree
    implicit none
    private

    public :: point_t, shape_t, ntree_t
    public :: make_boundary, make_range, make_ntree

contains

    !> 构建边界形状
    impure subroutine make_boundary(xmin, xmax, ratio, boundary, squared)
        real(rk), intent(in) :: xmin(:), xmax(:)
        integer, intent(in), optional :: ratio
        class(shape_t), intent(out), allocatable :: boundary
        logical, intent(in) :: squared
        integer ratio_
        if (present(ratio)) then
            ratio_ = ratio
        else
            ratio_ = 1
        end if
        select case (size(xmin))
        case (1)
            boundary = line_t((xmin + xmax)/2, ratio_*(xmax(1) - xmin(1)))
        case (2)
            if (squared) then
                boundary = square_t((xmin + xmax)/2, ratio_*(maxval(xmax - xmin)))
            else
                boundary = rectangle_t((xmin + xmax)/2, ratio_*(xmax - xmin))
            end if
        case (3)
            if (squared) then
                boundary = cube_t((xmin + xmax)/2, ratio_*(maxval(xmax - xmin)))
            else
                boundary = cuboid_t((xmin + xmax)/2, ratio_*(xmax - xmin))
            end if
        end select
    end subroutine make_boundary

    !> 构建查找域边界
    impure subroutine make_range(center, radius, range)
        real(rk), intent(in) :: center(:)
        real(rk), intent(in) :: radius
        class(shape_t), intent(out), allocatable :: range
        select case (size(center))
        case (1)
            range = line_t(center, radius*2)
        case (2)
            range = circle_t(center, radius)
        case (3)
            range = sphere_t(center, radius)
        end select
    end subroutine make_range

end module ntree_factory_m
